package Flickr::API::Rest;

use Digest::MD5 qw(md5_hex);
use LWP::Simple;
use XML::Simple;

our $VERSION = 0.01;

sub new {
	my ($class, $api_key, $secret, %params) = @_;
	my $self = {
		api_key => $api_key,
		secret  => $secret,
		%params,
	};
	bless $self, $class;
	return $self;
}

sub AUTOLOAD {
	my ($self, $args, $sign) = @_;
	
	my $method = $AUTOLOAD;
	
	$method =~ s/.*://; # trim off class qualifier
	$method =~ s/_/./g; # convert underscores to dots
	
	# First create default arguments...
	my %args = (
		api_key => $self->{api_key},
		method  => $method,
	);
	
	if (exists $self->{format}) {
		$args{format} = $self->{format};
	}
	
	# ... then add user-supplied args
	# (this lets the user override format on a per-method basis)
	%args = ( %args, %$args ) if defined $args;
	
	my $format = $args{'format'};
	if (exists $args{'format'} && $args{'format'} eq 'perl') {
		delete $args{'format'};
	}
	
	if ($sign) {
		$args{api_sig} = $self->get_api_sig(\%args);
	}

	my $url = 'http://api.flickr.com/services/rest/?';
	$url   .= join('&', map { "$_=" . $args{$_} } sort keys %args);
	my $result = get($url);
	
	if (defined $format && $format eq 'perl') {
		$result = XMLin($result);
	}
	return $result;
}

# need an explicit DESTROY method, otherwise it's handled by AUTOLOAD
sub DESTROY {}

sub get_api_key {
	my $self = shift;
	return $self->{api_key};
}

sub get_api_sig {
	my $self    = shift;
	my $args	= shift or return;
	my $result 	= $self->{secret};
	
	for my $key (sort keys %$args) {
		$result .= $key;
		$result .= $args->{$key};
	}
	return md5_hex($result);
}

1;

__END__

=head1 NAME

Flickr::API::Rest - A simple module for accessing the Flickr API via its REST interface

=head1 SYNOPSIS

	my $api_key = 'api_key_here';
	my $secret  = 'secret_here';

	my $flickr = new Flickr::API::Rest($api_key, $secret);

	# call flickr.photos.getContactsPhotos
	my $args = {
		count => 6,
		single_photo => 1,	
	};
	my $response = $flickr->flickr_photos_getContactsPhotos($args, 1);

	# $response contains reference to hash containing parsed XML response 

=head1 CONSTRUCTOR

=over

=item I<new($api_key, $secret)>

Create a new Flickr::API::Rest object using the specified API key and
secret.

=back

=head1 METHODS

=over

=item I<flickr_any_method($args [,$sign])>

Any Flickr API method, with dots replaced by underscores. C<$args>
is a reference to a hash containing method arguments.

If C<$sign> is true, the object will sign the method arguments
before submitting it. Use this for methods that are marked in the
API docs as needing to be authenticated.

=item I<get_api_key($args)>

Returns the object's API key

=item I<get_api_sig($args)>

Calculates the API signature for the given method arguments.

=back

=cut
